var Miracle={
	creatNew:function(c){
		var o = {};
		//html
		o.blockSuffix = '<div class="cle"></div>';
        o.blockPrefix = 'b';	//元素样式前缀
		o.cssClear = 'blockClear';	//被清除时的样式
		o.cssClick = 'blockClick';	//被点击时的样式
		//类属性
		o.row =	4;	//行数
		o.col =	8;	//列数
		o.count = o.row*o.col
		o.colorLen = 3;	//活动元素样式总数量
        o.clearCount = 0;    //总消除量
        //其他
        o.nowBlock = {};    //当前活动元素
        o.preBlock = {};    //上一个活动元素
        o.markBlocks = [];  //标记待消除索引集（暂存区）

		//====================事件====================
		//单元格点击事件
		o.bClick = function(){
			var isClear;
            o.nowBlock = o.infoBlock($(this));
            if(o.nowBlock['colorType'] == 0){
                return false;
            }
			o.nowBlock.addClass(o.cssClick);
			if(o.preBlock['id'] >= 0){
				//判断当前活动元素是否可以交换
				if(o.nowBlock['nearIndex'].indexOf(o.preBlock['id']) >= 0){
					o.changeClass();
					//判断是否有消除标记
					isClear = o.series();
					if(isClear > 0){
						o.bListenClear(isClear);
						o.cancle();
					}else{
						setTimeout(function(){
							o.changeClass();
							o.cancle();
						},500);
					}
				}else{
					o.cancle();
				}
			}else{
				o.preBlock = o.nowBlock;
			}
		};

		//还原样式
		o.cancle = function(){
			o.mainB.removeClass(o.cssClick);
			o.nowBlock = {};
            o.preBlock = {};
		};

		//监听动画结束事件
		o.bListenClear = function(index){
			if(index > 0){
				/*eListener(o.mainB.eq(index)[0],'webkitAnimationEnd',fun = function(){
					o.clear();
					if(index > 0){
						o.bListenClear(o.series());
					}
					eListener(o.mainB.eq(index)[0],'webkitAnimationEnd',fun,1);
				},0);*/
				//监听事件可能无效，暂时使用 setTimeout
				setTimeout(function(){
					o.clear();
					//加短暂延迟，否则填充无视觉效果
					setTimeout(function(){
						o.bListenClear(o.series());
					},10);
				},1000);
			}
		};

		//====================主消除过程方法====================
		//全局检测标记可消除的元素
		//返回：tCount 本次标记数量
		o.series = function(){
			var start,c,r,step;
			var tClass = '';	//当前编号
			var preClass = '';	//上一个编号
			var tCount = 0;
			tCount += o.seriesSpecial();
			//横向检索
			for(r = 0;r < o.row;r++){
				start = r * o.col;
				for(c = start;c <= (start + o.col);c++){
                    if(o.mainB.eq(c).length > 0){
                        tClass = o.getBlockType(o.mainB.eq(c));
                    }else{
                        tClass = -1;
                    }
					if(preClass != tClass || tClass == '0'){
                        if(o.markBlocks.length >= 3){
                            tCount += o.markIn(1);
                        }
                        o.markBlocks = [];
						preClass = tClass;
					}
                    //消除底部固定块
                    if(r == (o.row - 1) && tClass == 0){
                        o.markBlocks = [c];
                        tCount += o.markIn(3);
                    }
                    o.markBlocks.push(c);
				}
				preClass = '';
			}
            //纵向检索
            step = o.col;
            for(r = 0;r < o.col;r++){
				for(c = r;c <= (r + o.count - o.col);(c += step)){
                    if(o.mainB.eq(c).length > 0){
                        tClass = o.getBlockType(o.mainB.eq(c));
                    }else{
                        tClass = -1;
                    }
					if(preClass != tClass || tClass == '0'){
                        if(o.markBlocks.length >= 3){
                            tCount += o.markIn(2);
                        }
                        o.markBlocks = [];
						preClass = tClass;
					}
                    o.markBlocks.push(c);
				}
				preClass = '';
			}
            o.markBlocks = [];
            return tCount;
		};

		//检测特殊消除方式
		//参数，返回：与series方法一致
		o.seriesSpecial = function(){
            var tCount = 0;
            var tFun;
            //console.log(arguments);
            tFun = 'clear'+o.nowBlock['colorType'];
            if(o[tFun]){
                tCount += o[tFun](o.nowBlock);
            }
            tFun = 'clear'+o.preBlock['colorType'];
            if(o[tFun]){
                tCount += o[tFun](o.preBlock);
            }
            return tCount;
		};

		/*
		说明：写入消除标记
		参数：mode - 标记方式(1 横向，2 纵向，3 特殊)
		返回：标记数量
		*/
		o.markIn = function(mode){
            var count,rd;
            count = o.markBlocks.length;
            o.clearCount += count;
            console.log(o.clearCount);
            //生成特殊元素
            if(count >= 4 && (mode == 1 || mode == 2)){
                rd = 2;  //o.rd(0,count-1)
                o.mainB.eq(o.markBlocks[rd]).attr('class',o.setNewClass(mode == 1 ? 10 : 11));
                o.markBlocks.splice(rd,1);
                count = o.markBlocks.length;
            }
            for(var i = 0;i < count;i++){
                o.mainB.eq(o.markBlocks[i]).addClass(o.cssClear);
            }
            o.markBlocks = [];  //清除暂存区
            return count;
		};

		//消除标记并填充
		o.clear = function(){
			for(var i = o.count;i >= 0;i--){
				if(o.mainB.eq(i).hasClass(o.cssClear)){
					o.clearFill(o.mainB.eq(i));
				}
			}
			return true;
		};
		//递归填充
		o.clearFill = function(t){
			var id = t.index() - o.col;
			var className;
			if(id < 0){
				//顶部随机值
				className = o.setNewClass();
				t.attr('class',className);
				return className;
			}else{
				//循环填空
				var p = o.mainB.eq(id);
				if(p.hasClass(o.cssClear)){
					className = o.clearFill(p);
				}else{
					className = o.mainB.eq(id).attr('class');
				}
				o.mainB.eq(id).addClass(o.cssClear);
				t.attr('class',className);
				return className;
			}
		};
		//====================过程方法 END====================
        
        //特殊消除元素，以 class 编号作为方法后缀
        //整行，10
        o.clear10 = function(obj){
            var s,t;
            s = obj['id'] - obj['id'] % o.col;
            for(var i = s;i < s + o.col;i++){
                t = o.getBlockType(o.mainB.eq(i));
                if(t != 0){
                    o.markBlocks.push(i);
                }
            }
            return o.markIn(3);
        };
        //整列，11
        o.clear11 = function(obj){
            var s,t;
            s = obj['id'] - Math.floor(obj['id'] / o.col) * o.col;
            for(var i = s;i < o.count;i = i + o.col){
                t = o.getBlockType(o.mainB.eq(i));
                if(t != 0){
                    o.markBlocks.push(i);
                }
            }
            return o.markIn(3);
        };

		//==================初始化==================
		o.init = function(){
            //设置全局元素对象
			o.main = c.main ? $("#"+c.main) : $("#miracle");	//主容器对象
            //o.initBlock();
            o.mainB = o.main.children('.block');	//全部元素对象集
            //设置全局 css
            o.mainB.width(o.main.width() / o.col);
            o.main.children('.block').children('p').height(o.main.children('.block').children('p').width());
            
			o.bListenClear(o.series());	//初始化标记、清除
            //o.clearCount = 0;

			o.mainB.on('click',o.bClick);
		};
		//生成单元格
		o.initBlock = function(){
			//html
			var html = '';
            var n;
			for(var i = 0;i < o.count;i++){
				html += '<div class="'+o.setNewClass()+'"><p></p></div>';
			}
			o.main.html(html);
			o.main.append(o.blockSuffix);
			//样式
			var d = o.main.find('.block p');
			d.height(d.width());
		};
		//==================初始化 END==================

		//====================辅助方法====================
        //返回指定元素的信息
        //参数：索引值 || 元素对象
        o.infoBlock = function(index){
            var info = typeof index == 'object' ? index : o.mainB.eq(index);
            info['id'] = info.index();
            info['colorType'] = o.getBlockType(info);
            info['nearIndex'] = o.nearBlock(info['id']);
            return info;
        };
        
        //返回指定元素样式编号
        //参数：元素对象
        o.getBlockType = function(obj){
            var c;
            c = obj.attr('class');
            c = o.getFirstClass(c);
            c = c.replace(o.blockPrefix,'');
            return c;
        }
        
        //返回指定容器的周围 4 个相邻容器的索引值
        //参数：索引值 index 从 0 开始
        o.nearBlock = function(index){
            var arrIndex = [];
            var n;
            n = index - o.col;
            arrIndex[0] = n < 0 ? null : n;
            n = index + 1;
            arrIndex[1] = (n >= o.count || n % o.col == 0) ? null : n;
            n = index + o.col;
            arrIndex[2] = n >= o.count ? null : n;
            n = index - 1;
            arrIndex[3] = (n < 0 || n % o.col == o.col - 1) ? null : n;
            return arrIndex;
        };
        
		//交换并重置 2 个元素对象 class 值，不对元素对象进行逻辑验证
        //参数：目前不使用参数，直接调用内部对象
		o.changeClass = function(t1 = '',t2 = ''){
            var tp;
            tp = o.nowBlock.attr('class');
			o.nowBlock.attr('class',o.preBlock.attr('class'));
			o.preBlock.attr('class',tp);
            o.nowBlock['colorType'] = o.getBlockType(o.nowBlock);
            o.preBlock['colorType'] = o.getBlockType(o.preBlock);
		};

		//返回一个元素的初始class值
		//参数：n - 数字:样式编号,null:随机值
		o.setNewClass = function(n){
			var className;
			if(n >= 0){
				className = 'b'+n+' block';
			}else{
				className = 'b'+o.rd(1,o.colorLen)+' block';
			}
			return className;
		};

		//====================系统函数====================
		//生成随机数
		//参数：m - 下限，n - 上限
		o.rd = function(m,n){
			return parseInt(Math.random() * (n - m + 1) + m);
		};

		//返回字符串以 ‘ ’ 分隔的第一个值
		o.getFirstClass = function(classes){
			var arrClass = classes.split(' ');
			return arrClass[0];
		};

		return o;
	}
};

//el - js dom
function eListener(el,event,fun,remove){
	if(remove == "1"){
		el.removeEventListener(event,fun);
	}else{
		el.addEventListener(event,fun);
	}
}